#pragma once

#include "SocketTCP.h"
#include "FileSystem.h"
#include "../util\classlink.h"

class CSession
{	
	DECLARE_CLASS_LINK(CSession)

public:
	CSession(void);
	virtual ~CSession(void);

protected:
	BOOL			m_bIsReliableSession;
	DWORD			m_dwID;
	DWORD			m_dwTargetTask;
	DWORD			m_dwCurFileIOBytes;
	
	IFile*			m_pFile;
	CSockStream*	m_pSocket;

	CCriticalSectionBS	m_CS;

public:
	void	Close(DWORD dwReason);
	void	Reset();
	void	Invalidate();
	BOOL	Create(CSockStream* pSock, DWORD dwID, DWORD dwTargetTask);

	void	Link() { m_ClassLink.Link(); }
	void	Unlink() { m_ClassLink.Unlink(); }

	BOOL	SetEncodeContext(EncodeCtx& ec);
	long	SendMsg(CMsg* pMsg);
	void	SessionHandshakingCompleted();

	/******************************************************************
	// file transfering Invokers
	******************************************************************/
	BOOL	RecvFile(FILE_TYPE file_type, std::wstring strFileFullPath, DWORD dwFileSize, long nOffset = 0);
	BOOL	SendFile(FILE_TYPE file_type, std::wstring strFileFullPath, long nOffset = 0);
	size_t	CloseFile();

	/******************************************************************
	// file transfering event handlers
	******************************************************************/
	BOOL	OnFileDataSent(DWORD dwSendBytes);
	BOOL	OnFileDataReceived(DWORD dwWrittenBytes);

	/******************************************************************
	// misc.
	******************************************************************/
	void	SetAsReliableSession() { m_bIsReliableSession = TRUE; }
	BOOL	IsReliableSession() { return m_bIsReliableSession; }
	BOOL	IsValidSession(DWORD dwTimeout);
	
	long			GetCountOfOutstandingSend();
	DWORD			GetID() { return m_dwID; }
	CSockStream*	GetAssociatedSocket() { return m_pSocket; }
	IFile*			GetWorkingFile() { return m_pFile; }
	SESSION_TYPE	GetSessionType() { if (m_pSocket == NULL) return SESSION_TYPE_INVALID; return m_pSocket->GetSessionType(); }

	void	FileTransferCompleted(int io_mode, BOOL bSuccess);
	
	long	GetSessionCountOfClassLink() { return GET_CLASSLINK_CNT(CSession); }
		
protected:
	CTask*	_GetTargetTask();
	CTask*	_GetTask(DWORD dwTaskID);
	BOOL	_SetTask(DWORD dwTaskID);
	void	_PostMessagetoTargetService(WORD wNotifyMsg, DWORD dwData1, ULONG_PTR Data2);
	BOOL	_PrepareFileTransfer(FILE_TYPE file_type_to_open, std::wstring& strFileFullPath, DWORD dwForWrite, long nOffset);
	BOOL	_GeneratePathDir(std::wstring& strFullPath);
	int		_GetCurProgressPercent();
	
	friend class CSessionMgr;
};





















